/*
 * Lista.cpp
 *
 *  Created on: 08/11/2013
 *      Author: Miguel
 */

#include "Lista.h"

porId Lista::evalPorId;

Lista::Lista() {
	idTerm = 1;
	cantidadDeDocs = 0;
}

Lista::~Lista() {}

BigInt Lista::getIdTerm() const{
	return idTerm;
}

void Lista::crearConDoc(IDs id) {
	limpiar();
	idTerm = id.getIdTermino();
	docs.push_back(id.getIdDoc());
	frecuencias.push_back(id.getFrec());
	cantidadDeDocs = 1;
}

void Lista::limpiar() {
	idTerm = 1;
	docs.clear();
	frecuencias.clear();
	cantidadDeDocs = 0;
}

void Lista::agregarDoc(IDs id) {
	docs.push_back(id.getIdDoc());
	frecuencias.push_back(id.getFrec());
	cantidadDeDocs++;
}

void Lista::imprimir() {
	std::cout << "Cant. de Docs que contienen al Termino " << idTerm << ": " << cantidadDeDocs << std::endl;
	std::cout << "Lista de terminos: " << std::endl;
	for(int i=0; i<cantidadDeDocs; i++)
		std::cout << i+1 << ") idDoc: " << docs[i] << " frec: " << frecuencias[i] << std::endl;
}

int porId::eval(const Lista& unaLista) const {
	return unaLista.getIdTerm() - idTerm;
}

const porId& Lista::ById(BigInt id) {
	evalPorId.idTerm = id;
	return evalPorId;
}

void Lista::interseccion(Lista otra, Lista& interseccion) {
	BigIntVector::iterator itDoc1 = otra.docs.begin();
	BigIntVector::iterator itDoc2 = docs.begin();

	BigIntVector::iterator itFrec = otra.frecuencias.begin();

	while( itDoc1 != otra.docs.end() && itDoc2 != docs.end()) {
		if( *itDoc1 < *itDoc2 ) {
			itDoc1++;
			itFrec++;
		}
		else if ( *itDoc1 > *itDoc2 ){
			itDoc2++;
		}
		else{
			interseccion.docs.push_back(*itDoc1);
			interseccion.frecuencias.push_back(*itFrec);
			interseccion.cantidadDeDocs++;
			itDoc1++; itDoc2++; itFrec++;
		}
	}
}


void Lista::copiarDocumentos(std::vector<int>& docsDestino) {
	for( int i = 0; i<docs.size(); i++)
		docsDestino.push_back(docs[i]);
}
BigInt Lista::size() const {
	return 	sizeof(idTerm) +
			sizeof(cantidadDeDocs) +
			(docs.size() + frecuencias.size())*sizeof(BigInt);
}

Lista& Lista::operator=(const Lista otra) {
	idTerm = otra.idTerm;
	cantidadDeDocs = otra.cantidadDeDocs;
	docs = otra.docs;
	frecuencias = otra.frecuencias;
	return *this;
}

void Lista::serialize(ISerializer& serializer) const {
	serializer.serializeUnsignedLongInt(idTerm);
	serializer.serializeUnsignedLongInt(cantidadDeDocs);
	for( int i = 0; i < cantidadDeDocs; i++) {
		serializer.serializeUnsignedLongInt(docs[i]);
		serializer.serializeUnsignedLongInt(frecuencias[i]);
	}
}

void Lista::unserialize(IUnserializer& unserializer) {
	idTerm = unserializer.unserializeUnsignedLongInt();
	cantidadDeDocs = unserializer.unserializeUnsignedLongInt();
	for( int i = 0; i < cantidadDeDocs; i++) {
		docs.push_back(unserializer.unserializeUnsignedLongInt());
		frecuencias.push_back(unserializer.unserializeUnsignedLongInt());
	}
}
